package com.zzy.campus.job;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzy.campus.model.domain.User;
import com.zzy.campus.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class PreCatch {
    @Resource
    private UserService userService;

    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    @Resource
    private RedissonClient redissonClient;

    //重点用户,假定为1，后续需要搜东搜索
    //TODO
    private List<Long> mainUserList = new ArrayList<>();

    //每天xx时xx分执行，预热推荐用户 秒-分-时-日-月-年
    @Scheduled(cron = " 0 32 22 * * *")
    public void doCacheRecommendUser(){
        mainUserList.add(1L);
//        //查询所有用户，执行缓存预热
//        List<User> users = userService.list();
//        users.forEach(item-> mainUserList.add(item.getId()));
        log.info("执行推荐用户的缓存预热");

        RLock lock = redissonClient.getLock("campus:precatch:docatch:job");
        try {
            //抢锁,设置到期时间（等待时间0说明抢不到就不会抢，只有一个服务器执行该任务
            if(lock.tryLock(0,30000,TimeUnit.MILLISECONDS)){
                System.out.println("getlock :"+Thread.currentThread().getId());
                //具体业务代码
                for (Long userId: mainUserList){
                    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
                    //这里指定了预热的用户分页数量
                    Page<User> userPage = userService.page(new Page<>(1, 20), queryWrapper);
                    String redisKey = String.format("campus:user:recommend:%s", userId);
                    ValueOperations<String,Object> valueOperations = redisTemplate.opsForValue();
                    //写缓存
                    try {
                        valueOperations.set(redisKey,userPage,1000000, TimeUnit.MILLISECONDS);
                        System.out.println(redisTemplate.opsForValue().get(redisKey));
                    }catch (Exception e){
                        log.error("redis set key error",e);
                    }
                }
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }finally {
            //只能释放自己的锁
            if (lock.isHeldByCurrentThread()){
                System.out.println("unlock: "+Thread.currentThread().getId());
                lock.unlock();
            }
        }

    }
}
